//
//  GridNode.swift
//  iwe
//
//  Created by zhuxietong on 2018/9/1.
//  Copyright © 2018年 zhuxietong. All rights reserved.
//

import Foundation
import UIKit
import AsyncDisplayKit
import Eelay
public enum GridHeight{
    case px(CGFloat)
    case scale(CGFloat)
}



open class GridNode<Kit:GridCol,Space:ASDisplayNode>:MoDisplayNode,EeActionDelegate{
    open func active(onwer: Any, actionID: String, data: NSMutableDictionary) {
        self.delegate?.active(onwer: onwer, actionID: actionID, data: data)
    }
    
    
    public var itemWidth:CGFloat{
        get{
            let left_w:CGFloat = padding.right + padding.left + ((columnCount - 1).cg_floatValue * space.x)
            let w:CGFloat = (limtWidth  - left_w)/columnCount.cg_floatValue
            return w
        }
    }
    
    public var itemHeight:CGFloat{
        get{
            switch rowHeight {
            case .px(let px):
                return px
            case .scale(let scale):
                return itemWidth * scale
            }
        }
    }
    public var didLoadKits:(_:[Kit])->Void = {_ in}

    public var space:(x:CGFloat,y:CGFloat) = (0,0)
    public var columnCount:Int = 4
    public var rowHeight:GridHeight = GridHeight.scale(1)
    public var padding = UIEdgeInsets.zero
    public var limtWidth:CGFloat = Swidth
    
    public var spaceColor:UIColor = .clear
    public var nodePath = "items"
    var __items = [Kit]()
    var row_space = [Space]()
    var column_space = [Space]()
    public var items:[Kit]{
        get{
            var row = -1
            var column = 0
            var i:Int = 0
            for item in __items {
                switch i % columnCount {
                case 0:
                    row = row + 1
                    column = 0
                default:
                    column = column + 1
                }
                item.colum = column
                item.row = row
                item.index = i
                i = i + 1
            }
            return __items
        }
    }

    var rows:[[Kit]]{
        var rows_ = [[Kit]]()
    
//        var rowCount:Int = (__items.count / columnCount)
        var rowCount = 0
        
        for (i,_) in __items.enumerated() {
            if (i % columnCount) == 0{
                rowCount = rowCount + 1
            }
        }
        for i in 0..<rowCount {
            rows_.append(__items.filter { (t) -> Bool in
                return t.row == i
            })
            
          
        }
        
        return rows_
    }


    public override func mo_model_reload() {
        let datas = DataNode.path(node: nodePath, mo.model, value: NSMutableArray())
        __items = [Kit]()
        let space_ = Space()
        space_.backgroundColor = spaceColor
        row_space = [space_]
        
        
        weak var wself = self
        var row = -1
        var column = 0
        var i:Int = 0
        let columnCount_ = columnCount
        
        let w = itemWidth
        let h = itemHeight
        
        for item in Each<NSMutableDictionary>(datas) {
            let space = Space()
            space.backgroundColor = spaceColor
            column_space.append(space)
            let kit = Kit()
            kit.width = w
            kit.height = h
            switch i % columnCount_ {
            case 0:
                row = row + 1
                column = 0
                let space_row = Space()
                space_row.backgroundColor = spaceColor
                row_space.append(space_row)
            default:
                column = column + 1
            }
            kit.colum = column
            kit.row = row
            kit.index = i
            item["__index__"] = "\(i)"
            i = i + 1
            kit.mo.controller = wself?.mo.controller
            kit.delegate = self
            kit.mo.model = item
            __items.append(kit)
        }
      
        
        self.style.minWidth = ASDimension(unit: .points, value: limtWidth)
        self.style.maxWidth = ASDimension(unit: .points, value: limtWidth)
        self.invalidateCalculatedLayout()
        self.setNeedsLayout()
        didLoadKits(__items)
        
    }
    public var autoLayoutItemWith:Bool = false
    override public func specGetter() -> _Spec {
        
        let w = itemWidth //调整
        let h = itemHeight
        
        let rows = self.rows
        var rows_spec = [_Spec]()
        for (row_index,row) in rows.enumerated() {
            
//            print("-ss----LLL",row_index)
            var row_colums = [_Spec]()
            for column in row {
                let column_spec = column[w,"\(h)"]
                row_colums.append(column_spec)
                if (column.colum + 1) < columnCount{
                    let space_ = column_space[column.index]
                    row_colums.append(space_[space.x,"\(h)"])
                }
            }
            let row_spec = _Spec.stack(["h",&-.stretch,_justfy(.flex_start),_nowrap], childs: row_colums)
                rows_spec.append(row_spec)
//            if (row_index < (rows.count - 1))
//            {
                let row_space_ = row_space[row_index]
                rows_spec.append(row_space_["\(space.y)"])
//            }
        
        }
        if (rows_spec.count > 1){
            rows_spec.removeLast()
        }
//        print("-----OOOO",rows_spec.count)
       
        return _Spec.inset([], padding, child: _Spec.stack(["v",&-.stretch], childs: rows_spec))
        
    }
    
    
}


open class GridCol: MoDisplayNode {
    public var row:Int = -1
    public var colum:Int = -1
    public var index:Int = -1
    var isEmptyHold = false
    public var width:CGFloat = 0
    public var height:CGFloat = 0
    
    

    public let __touchBt = ASButtonNode()
    open override func didLayoutRules() {
        super.didLayoutRules()
        __touchBt.addTarget(self, action: #selector(colTouch), forControlEvents: .touchUpInside)
    }
    
    @objc open func colTouch(){
        active(ID: "colTouch")
    }
    override open func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {
        let spec = fastLayoutSpec(_spec: specGetter())
        return ASBackgroundLayoutSpec(child: spec, background: __touchBt)
    }
    
    public var activeAction:(Any,NSMutableDictionary)->Void = {_,_ in}

    
}





public class GridBaseNode<Kit:GridCol>:MoDisplayNode,EeActionDelegate{
    
    public func active(onwer: Any, actionID: String, data: NSMutableDictionary) {
        self.delegate?.active(onwer: self, actionID: actionID, data: data)
    }
    

    public var activeAction:(Any,NSMutableDictionary)->Void = {_,_ in}

    public var nodePath = "items"
    public override func mo_model_reload() {
        let datas = DataNode.path(node: nodePath, mo.model, value: NSMutableArray())
        __items = [Kit]()
        
        var item_index = 0
        weak var wself = self
    
        datas.list { (dict:NSMutableDictionary, i) in
            let kit = Kit()
            
            kit.mo.controller = wself?.mo.controller
            kit.delegate = wself
            dict["__index__"] = "\(i)"
            kit.mo.model = dict
            
            __items.append(kit)
            
            item_index = i
        }
        if fillLastRowBlank{
            var fillLastRowBlank_count = col - (__items.count % col)
            if __items.count % col == 0
            {
                fillLastRowBlank_count = 0
            }
            
            while fillLastRowBlank_count > 0 {
                let kit = Kit()
                kit.mo.model = ["__index__":"\(item_index)","__blank__":FK.YES].mutable_dictionary
                __items.append(kit)
                item_index = item_index + 1
                fillLastRowBlank_count = fillLastRowBlank_count - 1
            }
        }
        
        self.style.minWidth = ASDimension(unit: .points, value: limtWidth + 1)
        self.style.maxWidth = ASDimension(unit: .points, value: limtWidth + 1)
    }
    
    public var fillLastRowBlank = true
    
    public typealias ColKit = Kit
    
    public var space:(x:CGFloat,y:CGFloat) = (0,0)
    public var col:Int = 4
    public var height:GridHeight = GridHeight.scale(1)
    public var padding = UIEdgeInsets.zero
    public var limtWidth:CGFloat = Swidth
    
    var __items = [ColKit]()
    
    public var itemWidth:CGFloat{
        get{
            
            let left_w:CGFloat = padding.right + padding.left + ((col - 1).cg_floatValue * space.x)
            let w:CGFloat = (limtWidth  - left_w)/col.cg_floatValue
            
            return w
        }
    }
    
    public var itemHeight:CGFloat{
        get{
            switch height {
            case .px(let px):
                return px
            case .scale(let scale):
                return itemWidth * scale
            }
        }
    }
    public var items:[ColKit]{
        get{
            
            var row = -1
            var column = 0
            var i:Int = 0
            __items.forEach { (one) in
                switch i % col {
                case 0:
                    row = row + 1
                    column = 0
                default:
                    column = column + 1
                }
                one.colum = column
                one.row = row
                one.index = i
                
                i = i + 1
            }
            return __items
        }
    }
    
    override public func specGetter() -> _Spec {
        var specs = [_Spec]()
        let w = itemWidth //调整

        let h = itemHeight
        let kits = items
        for one in kits{
            var y_space_just = space.y
            if one.row == 0
            {
                y_space_just = 0
            }
           
            let stack = _Spec.inset([], UIEdgeInsets(top: y_space_just, left: 0, bottom: 0, right: 0), child: one[w,"\(h)"])
            specs.append(stack)
        }
        
        let wd = limtWidth - padding.left - padding.right
        return _Spec.inset([], padding, child: _Spec.stack(["h|\(space.x)",_wrap,_justfy(.space_between),wd], childs: specs))
        
    }
    
    
}
